#include "mainwindow.h"

#include <QActionGroup>
#include <QApplication>
#include <QDebug>
#include <QDir>
#include <QDockWidget>
#include <QElapsedTimer>
#include <QErrorMessage>
#include <QFile>
#include <QFileDialog>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QSettings>
#include <QStackedWidget>
#include <QTimer>
#include <QToolBar>
#include <QXmlStreamReader>

#include "LeIpc2581/Ipc2581.h"
#include "LeIpc2581/DocumentParser.h"

#include "Document.h"
#include "iviewer.h"
#include "layerviewer.h"
#include "nullviewer.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    auto fileMenu = menuBar()->addMenu("&File");
    auto optionsMenu = menuBar()->addMenu("&Options");

    QAction *action;
    QActionGroup *actionGroup;

    action = new QAction("&Anti aliasing", this);
    action->setCheckable(true);
    action->setChecked(m_antiAliasEnabled);
    connect(action, &QAction::toggled, this, &MainWindow::enableAntiAlias);
    optionsMenu->addAction(action);
    action = new QAction("&Transparent layers", this);
    action->setCheckable(true);
    action->setChecked(m_transparentLayersEnabled);
    connect(action, &QAction::toggled, this, &MainWindow::enableTransparentLayers);
    optionsMenu->addAction(action);
    action = new QAction("&Drop shadow effect", this);
    action->setCheckable(true);
    action->setChecked(m_dropShadowEffectEnabled);
    connect(action, &QAction::toggled, this, &MainWindow::enableDropShadowEffect);
    optionsMenu->addAction(action);
    action = new QAction("Use &OpenGL", this);
    action->setCheckable(true);
    action->setChecked(m_openGLEnabled);
    connect(action, &QAction::toggled, this, &MainWindow::enableOpenGL);
    optionsMenu->addAction(action);
    optionsMenu->addSection("Level of details");
    actionGroup = new QActionGroup(this);
    actionGroup->setExclusive(true);
    action = new QAction("&High", this);
    action->setCheckable(true);
    action->setChecked(true);
    action->setData(QVariant::fromValue<LevelOfDetails>(LevelOfDetails::High));
    actionGroup->addAction(action);
    action = new QAction("&Medium", this);
    action->setCheckable(true);
    action->setData(QVariant::fromValue<LevelOfDetails>(LevelOfDetails::Medium));
    actionGroup->addAction(action);
    action = new QAction("&Low", this);
    action->setCheckable(true);
    action->setData(QVariant::fromValue<LevelOfDetails>(LevelOfDetails::Low));
    actionGroup->addAction(action);
    connect(actionGroup, &QActionGroup::triggered,
            this, [this](QAction *which)
    {
        setLevelOfDetails(which->data().value<LevelOfDetails>());
    });
    optionsMenu->addActions(actionGroup->actions());

    action = fileMenu->addAction("&Open...");
    connect(action, &QAction::triggered,
            this, &MainWindow::requestOpenFile);

    QTimer *timer = new QTimer(this);
    timer->setSingleShot(true);
    connect(timer, &QTimer::timeout,
            [this]() {
        QSettings settings;
        settings.beginGroup(objectName());
        restoreGeometry(settings.value("geometry").toByteArray());
        restoreState(settings.value("state").toByteArray());
        settings.endGroup();
    });
    timer->start(0);
}

MainWindow::~MainWindow()
{
}

void MainWindow::requestOpenFile()
{
    QString fileName = QFileDialog::getOpenFileName(this, "Open IPC-2581B file",
                                                    QDir::currentPath(),
                                                    "IPC-2581B (*.xml)");
    if (fileName.isNull())
        return;

    if (m_layerViewer != nullptr)
        m_layerViewer->desactivate(this);
    delete m_layerViewer;
    m_layerViewer = new LayerViewer;
    setCentralWidget(m_layerViewer->centralWidget());
    QSettings settings;
    settings.beginGroup(objectName());
    //restoreGeometry(settings.value("geometry").toByteArray());
    restoreState(settings.value("state").toByteArray());
    settings.endGroup();

    QApplication::setOverrideCursor(Qt::WaitCursor);
    bool success = m_layerViewer->openFile(fileName);
    QApplication::restoreOverrideCursor();
    if (!success)
        QMessageBox::critical(this, "Error while opening file",
                              m_layerViewer->errorMessage());
    else
        m_layerViewer->activate(this);
}

void MainWindow::enableAntiAlias(bool enabled)
{
    m_antiAliasEnabled = enabled;
    m_layerViewer->enableAntiAlias(enabled);
}

void MainWindow::enableTransparentLayers(bool enabled)
{
    m_transparentLayersEnabled = enabled;
    m_layerViewer->enableTransparentLayers(enabled);
}

void MainWindow::enableDropShadowEffect(bool enabled)
{
    m_dropShadowEffectEnabled = enabled;
    m_layerViewer->enableDropShadowEffect(enabled);
}

void MainWindow::enableOpenGL(bool enabled)
{
    m_openGLEnabled = enabled;
    m_layerViewer->enableOpenGL(enabled);
}

void MainWindow::setLevelOfDetails(LevelOfDetails lod)
{
    m_levelOfDetails = lod;
    m_layerViewer->setLevelOfDetails(m_levelOfDetails);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event);

    if (m_layerViewer != nullptr)
        m_layerViewer->desactivate(this);

    QSettings settings;
    settings.beginGroup(objectName());
    settings.setValue("geometry", saveGeometry());
    settings.setValue("state", saveState());
    settings.endGroup();
}
